package ext.acae2.dms.parse.wc9;

import java.beans.PropertyVetoException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import wt.doc.WTDocument;
import wt.epm.EPMDocument;
import wt.epm.build.EPMBuildRule;
import wt.lifecycle.LifeCycleHelper;
import wt.lifecycle.State;
import wt.log4j.LogR;
import wt.method.RemoteAccess;
import wt.method.RemoteMethodServer;
import wt.part.WTPart;
import wt.session.SessionServerHelper;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.vc.VersionControlException;
import wt.vc.VersionControlHelper;
import ext.acae2.dms.bean.DocReferenceLinkBean;
import ext.acae2.dms.bean.DocumentBean;
import ext.acae2.dms.bean.EPMBuildRuleBean;
import ext.acae2.dms.bean.EPMDescribeLinkBean;
import ext.acae2.dms.bean.EPMDocumentBean;
import ext.acae2.dms.bean.EPMMemberLinkBean;
import ext.acae2.dms.bean.EPMReferenceLinkBean;
import ext.acae2.dms.bean.PartBean;
import ext.acae2.dms.bean.PartUsageLinkBean;
import ext.acae2.util.ParameterUtil;
import ext.acae2.util.QueryUtil;
import ext.acae2.util.VersionUtil;

public class LoadXml implements RemoteAccess {
	
    private static final Logger LOGGER = LogR.getLogger(LoadXml.class.getName());

	public static void main(String[] args) throws RemoteException, InvocationTargetException {
		RemoteMethodServer server = RemoteMethodServer.getDefault();
		server.setUserName("wcadmin");
		server.setPassword("wcadmin");
		server.invoke("run", LoadXml.class.getName(), null, new Class[]{}, new Object[]{});
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void run(Map<String, List> map) throws Exception {
		
		SessionServerHelper.manager.setAccessEnforced(false);
	    
		List<PartBean> partList = map.get(ParameterUtil.PARTBEAN);

		createPart(partList);

		List<EPMDocumentBean> epmDocList = map.get(ParameterUtil.EPMDOCUMENTBEAN);

		createEpmDocument(epmDocList);

		List<PartUsageLinkBean> partLinkList = map.get(ParameterUtil.PARTUSAGELINKBEAN);
		
		createPartUsageLink(partLinkList,partList,epmDocList);
		
		
		List<EPMMemberLinkBean> memberLinks = map.get(ParameterUtil.EPMMEMBERLINK);
		
		createEPMMemberLink(memberLinks,partList,epmDocList);
		
//		List<EPMBuildRuleBean> buildRuleLinks = map.get(ParameterUtil.EPMBUILDRULELINK);
//		
//		createEPMBuildRuleLink(buildRuleLinks);

//		List<EPMDescribeLinkBean> epmDocLinkList = map.get(ParameterUtil.EPMDESCRIBELINKBEAN);
//		
//		createEPMDescribeLink(epmDocLinkList);
		
		
		List<EPMReferenceLinkBean> refLinks = map.get(ParameterUtil.EPMREFERENCELINK);
		
		createEPMReferenceLink(refLinks,partList,epmDocList);

//		List<DocReferenceLinkBean> docLinkList = map.get(ParameterUtil.DOCREFERENCELINKBEAN);
//		
//		createDocReferenceLink(docLinkList);
		
		
		SessionServerHelper.manager.setAccessEnforced(true);
	}
	
	private static void createPart(List<PartBean> partList) throws WTPropertyVetoException, RemoteException, VersionControlException, WTException {
		for (int i = 0; i < partList.size(); i++) {
			LOGGER.debug("> Start Part " + i);
			
			PartBean partBean = partList.get(i);
			//first search by partNumber
			String number = partBean.getNumber().toUpperCase();
			String version = partBean.getVersion().substring(0,partBean.getVersion().lastIndexOf("."));
			String iteration = partBean.getVersion().substring(partBean.getVersion().lastIndexOf(".")+1);
			List<WTPart> list = new ArrayList<WTPart>();
			
			if (QueryUtil.getPartsByNumber(number).size() == 0) {
				//if not exist   new 
				WTPart newPart = PartFactory.getInstance().createPart(partList.get(i));
				
				newPart = (WTPart) LifeCycleHelper.service.setLifeCycleState(newPart, State.RELEASED);
				if (VersionUtil.isNewVersion(newPart, version)) {

					newPart = (WTPart) VersionControlHelper.service.newVersion(newPart);

					VersionUtil.setVersion(newPart, version);
					VersionUtil.setIteration(newPart, iteration);
					
					VersionControlHelper.service.insertNode(newPart, null, null, null, null);
					
				}
				
			} else {

				list = QueryUtil.getPartsByNumber(number);
				//remove link
				for (WTPart part: list) {
//					LinkFactory.removeUsageLink(part);
				}
				
				boolean flag = false;
				for (WTPart part: list) {

					//if exist  then  search Version
					if (!VersionUtil.isNewVersion(part, version)) {
						//if version equals true then give up
						//else new
						flag = true;
						break;
					}
				}
				
				if (!flag) {

					WTPart newVersionPart = QueryUtil.getPartByNumber(number);
					newVersionPart = (WTPart) LifeCycleHelper.service.setLifeCycleState(newVersionPart, State.RELEASED);
					if (VersionUtil.isNewVersion(newVersionPart, version)) {

						newVersionPart = (WTPart) VersionControlHelper.service.newVersion(newVersionPart);
						
						VersionUtil.setVersion(newVersionPart, version);
						VersionUtil.setIteration(newVersionPart, iteration);
						
						VersionControlHelper.service.insertNode(newVersionPart, null, null, null, null);
					}
				}
				
			}
			
			LOGGER.debug("> End Part " + i);
		}
	}
	
	@SuppressWarnings("deprecation")
	private static void createEpmDocument(List<EPMDocumentBean> epmDocList) throws VersionControlException, WTException, FileNotFoundException, PropertyVetoException, IOException {
		for (int i = 0; i < epmDocList.size(); i++) {
			LOGGER.debug("> Start EPMDocument " + i);
			
			EPMDocumentBean epmDocBean = epmDocList.get(i);
			String number = epmDocBean.getNumber().toUpperCase();
			String version = epmDocBean.getVersion().split("\\.")[0];
			String iteration = epmDocBean.getVersion().split("\\.")[1];
			List<EPMDocument> list = new ArrayList<EPMDocument>();
			
			if (QueryUtil.getEPMDocumentsByNumber(number).size() == 0) {
				//new 
				EPMDocument newDocument = EPMDocumentFactory.getInstance().createDocument(epmDocList.get(i));
				newDocument = (EPMDocument) LifeCycleHelper.service.setLifeCycleState(newDocument, State.RELEASED);
				
				if (VersionUtil.isNewVersion(newDocument, version) || VersionUtil.isNewIteration(newDocument, iteration)) {
					newDocument = (EPMDocument) VersionControlHelper.service.newIteration(newDocument);
					
					VersionUtil.setVersion(newDocument, version);
					VersionUtil.setIteration(newDocument, iteration);
					
					VersionControlHelper.service.insertNode(newDocument, null, null, null, null);
				}

			} else {
				list = QueryUtil.getEPMDocumentsByNumber(number);
				for (EPMDocument document : list) {
//					LinkFactory.removeEpmDescribeLink(document);
				}
				boolean flag = false;
				
				for (EPMDocument document : list) {
					if (!VersionUtil.isNewVersion(document, version) && !VersionUtil.isNewIteration(document, iteration)) {
						flag = true;
						break;
					}
					
				}
				
				if (!flag) {
					//new 
					EPMDocument newDocument = QueryUtil.getEPMDocumentByNumber(number);
					if(VersionUtil.isNewVersion(newDocument, version) || VersionUtil.isNewIteration(newDocument, iteration)) {
						newDocument = (EPMDocument) VersionControlHelper.service.newIteration(newDocument);
						
						VersionUtil.setVersion(newDocument, version);
						VersionUtil.setIteration(newDocument, iteration);
						
						VersionControlHelper.service.insertNode(newDocument, null, null, null, null);
					}

				}
			}
			
			LOGGER.debug("> End EPMDocument " + i);
		}
	}
	
	private static void createPartUsageLink(List<PartUsageLinkBean> partLinkList,List<PartBean> partList,List<EPMDocumentBean> epmList) throws Exception {
		for (int i = 0; i < partLinkList.size(); i++) {
			LOGGER.debug("> Start WTPartUsageLink " + i);
			
			LinkFactory.createLink(partLinkList.get(i),partList,epmList);
			
			LOGGER.debug("> End WTPartUsageLink " + i);
		}
	}
	
	private static void createEPMDescribeLink(List<EPMDescribeLinkBean> epmDocLinkList,List<PartBean> partList,List<EPMDocumentBean> epmList) throws Exception {
		for (int i = 0; i < epmDocLinkList.size(); i++) {
			LOGGER.debug("> Start EPMDescribeLink " + i);
			
			LinkFactory.createLink(epmDocLinkList.get(i), partList,epmList);
			
			LOGGER.debug("> End EPMDescribeLink " + i);
		}
	}
	
	private static void createEPMMemberLink(List<EPMMemberLinkBean> memberLinks,List<PartBean> partList,List<EPMDocumentBean> epmList) throws Exception{
		for(EPMMemberLinkBean memberLink:memberLinks){
			LinkFactory.createLink(memberLink,partList,epmList);
		}
		
	}
	
//	private static void createEPMBuildRuleLink(List<EPMBuildRuleBean> buildruleLinks) throws WTPropertyVetoException, WTException{
//		for(EPMBuildRuleBean buildRuleLink:buildruleLinks){
//			LinkFactory.getInstance().createLink(buildRuleLink);
//		}
//		
//	}
	
	private static void createEPMReferenceLink(List<EPMReferenceLinkBean> refLinks,List<PartBean> partList,List<EPMDocumentBean> epmList) throws Exception{
		for(EPMReferenceLinkBean refLink:refLinks){
			LinkFactory.createLink(refLink,partList,epmList);
		}
	}
}
